﻿// <copyright file="HistoryViewControl.xaml.cs" company="Soumya Chattopadhyay">
// Copyright (c) 2010 All Right Reserved
// </copyright>
// <disclaimer> This software is intented for educational purposes only and not for 
// commerical or prodution use. The software is provided "as is", without warranty 
// of any kind, express or implied, including but not limited to the warranties of 
// merchantability, fitness for a particular purpose and noninfringement. In no event 
// shall the author(s) or copyright holder(s) be liable for any claim, damages or other 
// liability, whether in an action of contract, tort or otherwise, arising from, out of 
// or in connection with the software or the use or other dealings in the software.
// </disclaimer>

namespace My.CodePlex.TFSExplorer.Controls
{
    using System;
    using System.Collections;
    using System.Collections.ObjectModel;
    using System.IO;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Shapes;
    using Microsoft.TeamFoundation.VersionControl.Client;
    using Microsoft.TeamFoundation.VersionControl.Common;
    using My.CodePlex.TFSExplorer.TeamFoundation;

    /// <summary>
    /// Interaction logic for HistoryViewControl.xaml
    /// </summary>
    public partial class HistoryViewControl : UserControl
    {
        #region Fields

        /// <summary>
        /// The source item
        /// </summary>
        private SourceItem sourceItem;

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the HistoryViewControl class
        /// </summary>
        public HistoryViewControl()
        {
            InitializeComponent();

            this.PreviewMouseRightButtonDown += this.HistoryViewControl_PreviewMouseRightButtonDown;
        }

        #endregion

        #region Events

        /// <summary>
        /// The view details event
        /// </summary>
        public event Action<UserControl> ViewDetails;

        #endregion

        #region Public Methods

        /// <summary>
        /// Populate this control
        /// </summary>
        /// <param name="sourceItem">The source item</param>
        public void Populate(SourceItem sourceItem)
        {
            this.sourceItem = sourceItem;
            ObservableCollection<Changeset> obsCollection = new ObservableCollection<Changeset>();

            IEnumerable changeSetCollection = TeamFoundationContext.VersionControlServer.QueryHistory(sourceItem.ServerItem, VersionSpec.Latest, 0, RecursionType.Full, string.Empty, null, VersionSpec.Latest, Int32.MaxValue, true, false);
            foreach (var change in changeSetCollection)
            {
                Changeset changeset = change as Changeset;
                obsCollection.Add(changeset);
            }

            this.SourceHistoryView.ItemsSource = obsCollection;
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// On right mouse down, display the right context menu items
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void HistoryViewControl_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            // Check if one or two files are selected
            if (this.SourceHistoryView.SelectedItems != null)
            {
                // Collapse all
                this.SourceHistoryViewContextMenu.Visibility = Visibility.Collapsed;
                this.SourceHistoryViewCompare.Visibility = Visibility.Collapsed;
                this.SourceHistoryViewDetails.Visibility = Visibility.Collapsed;

                if (this.SourceHistoryView.SelectedItems.Count == 1)
                {
                    this.SourceHistoryViewContextMenu.Visibility = Visibility.Visible;
                    this.SourceHistoryViewDetails.Visibility = Visibility.Visible;
                }
                else if (this.SourceHistoryView.SelectedItems.Count == 2)
                {
                    if (!this.sourceItem.IsFolder)
                    {
                        this.SourceHistoryViewContextMenu.Visibility = Visibility.Visible;
                        this.SourceHistoryViewCompare.Visibility = Visibility.Visible;
                    }
                }
            }
        }

        /// <summary>
        /// Handle the 'Compare' context menu item click
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void CompareClick(object sender, RoutedEventArgs e)
        {
            if (this.SourceHistoryView.SelectedItems != null)
            {
                if (this.SourceHistoryView.SelectedItems.Count == 2)
                {
                    Changeset sitem1 = this.SourceHistoryView.SelectedItems[0] as Changeset;
                    Changeset sitem2 = this.SourceHistoryView.SelectedItems[1] as Changeset;

                    Item item1 = TeamFoundationContext.VersionControlServer.GetItem(this.sourceItem.Id, sitem1.ChangesetId);
                    Item item2 = TeamFoundationContext.VersionControlServer.GetItem(this.sourceItem.Id, sitem2.ChangesetId);

                    DiffOptions options = new DiffOptions();
                    options.UseThirdPartyTool = true;
                    options.Flags = DiffOptionFlags.EnablePreambleHandling | DiffOptionFlags.IgnoreWhiteSpace;
                    options.OutputType = DiffOutputType.Unified;
                    options.TargetEncoding = Console.OutputEncoding;
                    options.SourceEncoding = Console.OutputEncoding;
                    options.StreamWriter = new StreamWriter(Console.OpenStandardOutput(), Console.OutputEncoding);
                    options.StreamWriter.AutoFlush = true;

                    DiffItemVersionedFile diffItem1 = new DiffItemVersionedFile(item1, new ChangesetVersionSpec(item1.ChangesetId));
                    DiffItemVersionedFile diffItem2 = new DiffItemVersionedFile(item2, new ChangesetVersionSpec(item2.ChangesetId));

                    Difference.DiffFiles(TeamFoundationContext.VersionControlServer, diffItem1, diffItem2, options, item1.ServerItem, false);
                }
            }
        }

        /// <summary>
        /// Hanle the 'View Changeset details' context menu item click
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void ViewChangesetDetailsClick(object sender, RoutedEventArgs e)
        {
            if (this.SourceHistoryView.SelectedItem != null)
            {
                Changeset changeSet = this.SourceHistoryView.SelectedItem as Changeset;
                Changeset fullChangeSet = TeamFoundationContext.VersionControlServer.GetChangeset(changeSet.ChangesetId);

                ChangeSetDetailsControl changeSetDetailsControl = new ChangeSetDetailsControl();
                ChangeSetItem changeSetItem = new ChangeSetItem();

                if (fullChangeSet != null)
                {
                    Change[] changeArray = fullChangeSet.Changes;
                    foreach (var change in changeArray)
                    {
                        changeSetItem = new ChangeSetItem();
                        changeSetItem.Comment = fullChangeSet.Comment;
                        changeSetItem.CreatedOn = fullChangeSet.CreationDate;
                        changeSetItem.Name = System.IO.Path.GetFileName(change.Item.ServerItem);
                        changeSetItem.Folder = change.Item.ServerItem;
                        changeSetItem.Change = change.ChangeType.ToString();
                        changeSetItem.ChangeSet = fullChangeSet.ChangesetId.ToString();
                        changeSetItem.ByUser = fullChangeSet.Owner;
                        changeSetDetailsControl.ChangeSetDetailsView.Items.Add(changeSetItem);
                        changeSetDetailsControl.Tag = "Changeset #" + fullChangeSet.ChangesetId.ToString();
                    }
                }

                changeSetDetailsControl.DataContext = changeSetItem;

                if (this.ViewDetails != null)
                {
                    this.ViewDetails(changeSetDetailsControl);
                }
            }
        }

        #endregion
    }
}
